/**
 * AI服务层
 * 提供高级AI功能，封装业务逻辑
 */

import { OpenAIClient } from './openaiClient'
import { 
  AIResult, 
  RoleBasedGenerationRequest,
  RoleBasedRewriteRequest,
  RoleStyleAnalysis,
  AIRole
} from './types'
import { AIRoleService } from './roleService'

export interface AIServiceConfig {
  openaiApiKey: string
  baseURL?: string              // API基础URL
  model?: string
  contextLength?: number        // 提取上下文的字符数，默认1000
  roleService?: AIRoleService   // 角色服务实例
}

export class AIService {
  private client: OpenAIClient
  private config: AIServiceConfig
  private roleService?: AIRoleService

  constructor(config: AIServiceConfig) {
    this.config = {
      model: 'gpt-3.5-turbo',
      contextLength: 1000,
      ...config
    }

    this.client = new OpenAIClient({
      apiKey: config.openaiApiKey,
      baseURL: config.baseURL,
      model: config.model
    })

    this.roleService = config.roleService
  }

  /**
   * 通用文本生成
   * 直接发送完整的prompt给AI，不进行额外的上下文处理
   */
  async generateText(params: {
    prompt: string             // 完整的prompt
    maxTokens?: number         // 最大token数，默认1000
    temperature?: number       // 温度参数，默认0.7
  }): Promise<AIResult<string>> {
    console.log('[AI服务] 开始生成文本', {
      promptLength: params.prompt.length,
      maxTokens: params.maxTokens || 1000,
      temperature: params.temperature || 0.7
    })

    // 调用AI生成（使用generateText而不是complete，避免添加额外的system消息）
    const result = await this.client.generateText({
      prompt: params.prompt,
      maxTokens: params.maxTokens || 1000,
      temperature: params.temperature ?? 0.7
    })

    if (!result.ok) {
      return result
    }

    return {
      ok: true,
      data: result.data.content
    }
  }

  /**
   * 根据编辑器上下文生成续写内容
   */
  async continueWriting(params: {
    fullText: string           // 完整文档内容
    cursorPosition: number     // 光标位置（字符偏移量）
    maxTokens?: number         // 可选的最大token数,默认500
  }): Promise<AIResult<string>> {
    console.log('[AI服务] 开始生成续写内容', {
      fullTextLength: params.fullText.length,
      cursorPosition: params.cursorPosition,
      maxTokens: params.maxTokens || 500
    })

    // 提取光标前的上下文
    const context = this.extractContext(params.fullText, params.cursorPosition)

    // 构建提示词
    const prompt = this.buildContinuePrompt(context)

    // 调用AI生成
    const result = await this.client.complete({
      prompt,
      maxTokens: params.maxTokens || 500,
      temperature: 0.7
    })

    if (!result.ok) {
      return result
    }

    return {
      ok: true,
      data: result.data.content
    }
  }

  /**
   * 提取上下文
   * 提取光标前的最后N个字符作为上下文
   */
  private extractContext(text: string, position: number): string {
    const contextLength = this.config.contextLength!
    const start = Math.max(0, position - contextLength)
    const context = text.substring(start, position)

    console.log('[AI服务] 上下文提取', {
      contextLength: context.length,
      excerpt: context.substring(Math.max(0, context.length - 100))  // 最后100字
    })

    return context
  }

  /**
   * 构建续写提示词
   */
  private buildContinuePrompt(context: string): string {
    return `请根据以下内容续写，保持文风一致、内容连贯：

${context}

继续写：`
  }

  /**
   * 润色文本（预留接口，后续实现）
   */
  async polishText(text: string): Promise<AIResult<string>> {
    const prompt = `请润色以下文本，使其更加通顺、专业：

${text}

润色后的文本：`

    const result = await this.client.complete({
      prompt,
      maxTokens: text.length * 2,  // 润色后长度可能增加
      temperature: 0.5  // 润色时降低创造性
    })

    if (!result.ok) {
      return result
    }

    return {
      ok: true,
      data: result.data.content
    }
  }

  /**
   * 生成大纲（预留接口，后续实现）
   */
  async generateOutline(topic: string): Promise<AIResult<string>> {
    const prompt = `请为以下主题生成文章大纲：

主题：${topic}

大纲：`

    const result = await this.client.complete({
      prompt,
      maxTokens: 800,
      temperature: 0.8  // 大纲生成需要更高创造性
    })

    if (!result.ok) {
      return result
    }

    return {
      ok: true,
      data: result.data.content
    }
  }

  /**
   * 基于角色的内容生成
   */
  async generateWithRole(request: RoleBasedGenerationRequest): Promise<AIResult<string>> {
    console.log('[AI服务] 基于角色生成内容', {
      roleId: request.roleId,
      promptLength: request.prompt.length
    })

    if (!this.roleService) {
      return {
        ok: false,
        error: {
          code: 'role_service_not_available',
          message: '角色服务不可用',
          details: 'roleService未初始化'
        }
      }
    }

    try {
      // 获取角色信息
      const roleResult = await this.roleService.getRoleById(request.roleId)
      if (!roleResult.ok) {
        return {
          ok: false,
          error: roleResult.error
        }
      }

      if (!roleResult.data) {
        return {
          ok: false,
          error: {
            code: 'role_not_found',
            message: '角色不存在',
            details: { roleId: request.roleId }
          }
        }
      }

      const role = roleResult.data

      // 生成System Prompt
      const systemPrompt = this.roleService.generateSystemPrompt(role, {
        context: request.context
      })

      // 构建完整的提示词
      const fullPrompt = `${systemPrompt}

用户请求：${request.prompt}

请以${role.name}的身份完成以上任务。`

      // 调用AI生成
      const result = await this.client.complete({
        prompt: fullPrompt,
        maxTokens: request.maxTokens || 1000,
        temperature: request.temperature ?? role.settings.temperature
      })

      if (!result.ok) {
        return result
      }

      console.log('[AI服务] 角色生成成功', {
        roleId: request.roleId,
        roleName: role.name,
        outputLength: result.data.content.length
      })

      return {
        ok: true,
        data: result.data.content
      }
    } catch (error) {
      console.error('[AI服务] 角色生成失败', error)
      return {
        ok: false,
        error: {
          code: 'role_generation_failed',
          message: '基于角色的内容生成失败',
          details: error
        }
      }
    }
  }

  /**
   * 基于角色的内容改写
   */
  async rewriteWithRole(request: RoleBasedRewriteRequest): Promise<AIResult<string>> {
    console.log('[AI服务] 基于角色改写内容', {
      roleId: request.roleId,
      rewriteType: request.rewriteType,
      textLength: request.text.length
    })

    if (!this.roleService) {
      return {
        ok: false,
        error: {
          code: 'role_service_not_available',
          message: '角色服务不可用',
          details: 'roleService未初始化'
        }
      }
    }

    try {
      // 获取角色信息
      const roleResult = await this.roleService.getRoleById(request.roleId)
      if (!roleResult.ok) {
        return {
          ok: false,
          error: roleResult.error
        }
      }

      if (!roleResult.data) {
        return {
          ok: false,
          error: {
            code: 'role_not_found',
            message: '角色不存在',
            details: { roleId: request.roleId }
          }
        }
      }

      const role = roleResult.data

      // 生成System Prompt
      const systemPrompt = this.roleService.generateSystemPrompt(role, {
        context: request.context
      })

      // 根据改写类型构建提示词
      const rewritePrompts = {
        polish: `请润色以下文本，使其更符合${role.name}的写作风格：`,
        expand: `请扩写以下文本，添加更多细节和内容，保持${role.name}的写作风格：`,
        compress: `请压缩以下文本，提取核心观点，保持${role.name}的写作风格：`,
        restyle: `请重新表达以下文本，完全采用${role.name}的写作风格和语气：`
      }

      const taskPrompt = rewritePrompts[request.rewriteType] || rewritePrompts.polish

      const fullPrompt = `${systemPrompt}

${taskPrompt}

原文：
${request.text}

改写后的文本：`

      // 调用AI改写
      const result = await this.client.complete({
        prompt: fullPrompt,
        maxTokens: request.maxTokens || Math.max(request.text.length * 1.5, 500),
        temperature: role.settings.temperature
      })

      if (!result.ok) {
        return result
      }

      console.log('[AI服务] 角色改写成功', {
        roleId: request.roleId,
        roleName: role.name,
        rewriteType: request.rewriteType,
        originalLength: request.text.length,
        rewrittenLength: result.data.content.length
      })

      return {
        ok: true,
        data: result.data.content
      }
    } catch (error) {
      console.error('[AI服务] 角色改写失败', error)
      return {
        ok: false,
        error: {
          code: 'role_rewrite_failed',
          message: '基于角色的内容改写失败',
          details: error
        }
      }
    }
  }

  /**
   * 角色风格分析
   */
  async analyzeRoleStyle(roleId: string, sampleText: string): Promise<AIResult<RoleStyleAnalysis>> {
    console.log('[AI服务] 分析角色风格匹配度', {
      roleId,
      textLength: sampleText.length
    })

    if (!this.roleService) {
      return {
        ok: false,
        error: {
          code: 'role_service_not_available',
          message: '角色服务不可用',
          details: 'roleService未初始化'
        }
      }
    }

    try {
      // 获取角色信息
      const roleResult = await this.roleService.getRoleById(roleId)
      if (!roleResult.ok) {
        return {
          ok: false,
          error: roleResult.error
        }
      }

      if (!roleResult.data) {
        return {
          ok: false,
          error: {
            code: 'role_not_found',
            message: '角色不存在',
            details: { roleId }
          }
        }
      }

      const role = roleResult.data

      const analysisPrompt = `请分析以下文本是否符合${role.name}的写作风格。

角色特点：
- 语气：${role.settings.tone}
- 风格：${role.settings.style}
- 目标读者：${role.settings.targetAudience}

待分析文本：
${sampleText}

请从以下角度分析：
1. 风格匹配度（0-100分）
2. 具体的风格改进建议

请以JSON格式回复：
{
  "styleMatch": 匹配度分数(0-100),
  "suggestions": ["建议1", "建议2", "建议3"]
}`

      const result = await this.client.complete({
        prompt: analysisPrompt,
        maxTokens: 500,
        temperature: 0.3  // 分析需要较低的创造性
      })

      if (!result.ok) {
        return result
      }

      try {
        // 尝试解析JSON响应
        const analysis = JSON.parse(result.data.content)
        
        // 验证和规范化数据
        const styleMatch = Math.max(0, Math.min(100, analysis.styleMatch || 0)) / 100
        const suggestions = Array.isArray(analysis.suggestions) 
          ? analysis.suggestions.slice(0, 5)  // 最多5条建议
          : []

        console.log('[AI服务] 风格分析完成', {
          roleId,
          roleName: role.name,
          styleMatch,
          suggestionCount: suggestions.length
        })

        return {
          ok: true,
          data: {
            styleMatch,
            suggestions
          }
        }
      } catch (parseError) {
        // 如果JSON解析失败，提供默认分析结果
        console.warn('[AI服务] 风格分析结果解析失败，使用默认值', parseError)
        return {
          ok: true,
          data: {
            styleMatch: 0.5,  // 默认中等匹配度
            suggestions: ['请参考角色的写作风格特点进行调整']
          }
        }
      }
    } catch (error) {
      console.error('[AI服务] 角色风格分析失败', error)
      return {
        ok: false,
        error: {
          code: 'style_analysis_failed',
          message: '角色风格分析失败',
          details: error
        }
      }
    }
  }

  /**
   * 设置角色服务
   */
  setRoleService(roleService: AIRoleService): void {
    this.roleService = roleService
  }

  /**
   * 基于当前角色的续写（增强版本）
   */
  async continueWritingWithCurrentRole(params: {
    fullText: string
    cursorPosition: number
    roleId?: string  // 可选的特定角色ID
  }): Promise<AIResult<string>> {
    console.log('[AI服务] 基于角色的续写', {
      fullTextLength: params.fullText.length,
      cursorPosition: params.cursorPosition,
      roleId: params.roleId
    })

    // 如果没有指定角色或角色服务不可用，使用原始续写方法
    if (!params.roleId || !this.roleService) {
      return this.continueWriting({
        fullText: params.fullText,
        cursorPosition: params.cursorPosition
      })
    }

    // 提取上下文
    const context = this.extractContext(params.fullText, params.cursorPosition)

    // 使用角色生成续写内容
    return this.generateWithRole({
      roleId: params.roleId,
      prompt: `请根据以下上下文继续写作，保持内容连贯和风格一致：

${context}

继续写：`,
      context: context,
      maxTokens: 500
    })
  }

  /**
   * 生成文章标题建议
   * 根据文章内容生成多个标题选项供用户选择
   */
  async generateTitleSuggestions(params: {
    content: string        // 文章内容
    count?: number        // 生成标题数量，默认5个
  }): Promise<AIResult<string[]>> {
    console.log('[AI服务] 生成标题建议', {
      contentLength: params.content.length,
      count: params.count || 5
    })

    const count = params.count || 5

    // 提取文章开头用于分析（最多2000字）
    const contentPreview = params.content.substring(0, 2000)

    // 构建Prompt
    const prompt = `你是一位专业的内容编辑，请为以下文章生成${count}个不同风格的标题建议。

【文章内容】
${contentPreview}${params.content.length > 2000 ? '\n...' : ''}

【标题要求】
1. 每个标题8-20个字
2. 准确概括文章主题和核心价值
3. 提供不同风格的标题：
   - 平实型：客观陈述，适合正式场合
   - 吸引型：具有吸引力，激发阅读兴趣
   - 悬念型：设置疑问或悬念
   - 数字型：使用数字增强可信度
   - 情感型：触动读者情感

【输出格式】
请严格按照以下JSON格式输出，每行一个标题：
{
  "titles": [
    "标题1",
    "标题2",
    "标题3",
    "标题4",
    "标题5"
  ]
}

只输出JSON，不要其他内容。`

    console.log('[AI服务] 标题建议Prompt:')
    console.log('================== Prompt开始 ==================')
    console.log(prompt)
    console.log('================== Prompt结束 ==================')

    const result = await this.client.complete({
      prompt,
      maxTokens: 500,
      temperature: 0.8  // 使用较高的温度以获得更多样化的标题
    })

    if (!result.ok) {
      console.error('[AI服务] 标题建议生成失败:', result.error)
      return {
        ok: false,
        error: result.error
      }
    }

    try {
      // 清理markdown代码块标记
      let cleanContent = result.data.content.trim()

      if (cleanContent.startsWith('```json')) {
        cleanContent = cleanContent.replace(/^```json\s*\n/, '')
      } else if (cleanContent.startsWith('```')) {
        cleanContent = cleanContent.replace(/^```\s*\n/, '')
      }

      if (cleanContent.endsWith('```')) {
        cleanContent = cleanContent.replace(/\n```\s*$/, '')
      }

      // 解析JSON
      const parsed = JSON.parse(cleanContent)

      if (!parsed.titles || !Array.isArray(parsed.titles)) {
        throw new Error('返回的JSON格式不正确')
      }

      // 清理标题（移除引号、换行等）
      const titles = parsed.titles.map((title: string) => {
        let cleaned = title.trim()
        cleaned = cleaned.replace(/^["'「『]|["'」』]$/g, '') // 移除首尾引号
        cleaned = cleaned.substring(0, 50) // 限制最大长度
        return cleaned
      }).filter((title: string) => title.length > 0) // 过滤空标题

      console.log('[AI服务] 生成的标题建议:', titles)

      return {
        ok: true,
        data: titles
      }
    } catch (error) {
      console.error('[AI服务] 解析标题建议失败:', error)
      console.error('[AI服务] AI返回内容:', result.data.content)

      // 如果JSON解析失败，尝试按行分割
      const lines = result.data.content
        .split('\n')
        .map(line => line.trim())
        .filter(line => line.length > 0 && !line.startsWith('{') && !line.startsWith('}') && !line.includes('titles'))
        .slice(0, count)

      if (lines.length > 0) {
        console.log('[AI服务] 使用备用解析，生成的标题:', lines)
        return {
          ok: true,
          data: lines
        }
      }

      return {
        ok: false,
        error: {
          code: 'title_parsing_failed',
          message: '标题建议解析失败',
          details: error
        }
      }
    }
  }
}
